# -*- coding: utf-8 -*-
# @Time    : 2021/8/13 20:40
# @Author  : Flora.Chen
# @File    : run.py.py
# @Software: PyCharm
# @Desc: 框架主入口

"""
说明：
1、用例创建原则，测试文件名必须以“test”开头，测试函数必须以“test”开头。
2、运行方式：
  > python run.py  (回归模式，生成HTML报告)
  > python run.py -m debug  (调试模式)
"""

import pytest
from config.settings import REPORT_DIR, LOG_DIR, email, LIB_DIR
from loguru import logger
import os
import threading
from common.handle_yagmail import EmailServe
import click
from config.settings import RunConfig
import os
from common.handle_platform import HandlePlatform
from common.helper import zip_file

# import sys
# # 将allure的路径放到sys目录里去，方便框架识别
# sys.path.append(allure_path)

# 存放测试结果的目录，会生成一推json文件
result_dir = os.path.join(REPORT_DIR, 'allure_results')
allure_report = os.path.join(REPORT_DIR, 'allure_report')


def run_pytest(arg=None):
    # 执行前清除allure_result数据，避免生成报告时，会把上次执行的数据带进去
    args = ['-v', '-s', "--cache-clear", f'--alluredir={result_dir}', '--clean-alluredir']
    # args = ['-v', '-s', "-m api", "--cache-clear", f'--alluredir={result_dir}', '--clean-alluredir']
    if arg is not None:
        if isinstance(arg, str):
            args.append(arg)
        elif isinstance(arg, list):
            for item in arg:
                args.append(item)
        else:
            logger.error("arg参数格式有误！仅支持str和list.")
    pytest.main(args=args)


def general_report():
    platform = HandlePlatform()
    allure_path = os.path.join(LIB_DIR, [i for i in os.listdir(LIB_DIR) if i.startswith("allure")][0], "bin")
    # 调用cmd方法 report.allure，根据windows或linux环境判断
    # 然后执行生成报告的方法generate
    # --clean 覆盖路径，将上次的结果覆盖掉
    cmd = "{} generate {} -o {} --clean".format(os.path.join(allure_path, platform.allure), result_dir, allure_report)
    # os.popen() 方法用于从一个命令打开一个管道。在Unix，Windows中有效
    # 执行命令行命令，并通过read()方法将命令的结果返回
    logger.debug(os.popen(cmd).read())
    zip_file(file_path=allure_report, out_path=os.path.join(os.path.dirname(allure_report), "autotest_report.zip"))


def send_email():
    # 发送邮件
    send = EmailServe()
    send.send_email(email)
    # 删除本地附件
    os.remove(email['enclosures'])


@click.command()
@click.option("-r", default=None, help="输入运行模式：run 或 debug")
@click.option("-env", default=None, help="输入运行环境：test 或 live")
@click.option("-m", default=None, help="选择需要运行的用例：python.ini配置的名称")
def run(r, env, m):
    if r is None or r == "run":
        logger.add(os.path.join(LOG_DIR, "runtime_{time}.log"), enqueue=True, encoding="utf-8", rotation="00:00")
        logger.info("""
                     _    _         _      _____         _
      __ _ _ __ (_)  / \\  _   _| |_ __|_   _|__  ___| |_
     / _` | "_ \\| | / _ \\| | | | __/ _ \\| |/ _ \\/ __| __|
    | (_| | |_) | |/ ___ \\ |_| | || (_) | |  __/\\__ \\ |_
     \\__,_| .__/|_/_/   \\_\\__,_|\\__\\___/|_|\\___||___/\\__|
          |_|
          Starting      ...     ...     ...
        """)
        arg_list = ["--maxfail", RunConfig.max_fail, "--reruns", RunConfig.rerun]
        if env == "live":
            arg_list.append("--env=live")
        if m is not None:
            arg_list.append(f"-m={m}")
        # 创建两个线程，分别执行两个方法
        run = threading.Thread(target=run_pytest(arg_list))
        gen = threading.Thread(target=general_report)
        email = threading.Thread(target=send_email)
        run.start()
        # 先执行第一个线程，这个线程执行完才会执行下面的线程和主线程
        run.join()
        gen.start()
        gen.join()
        email.start()
        email.join()
        logger.info("#----------------------------TEST END-----------------------------------#")
    elif r == "debug":
        print("debug模式，开始执行！")
        run_pytest()
        print("运行结束！！")


if __name__ == '__main__':
    run()
